package com.bugsnag.ohos.util;

import com.bugsnag.ohos.TextUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;

/**
 * 系统属性读取工具类
 *
 * @since 2021-03-26
 */
public class PropHelper {
    /**
     * 默认读取值
     */
    public static final String DEFAULT_VALUE = "unknown";
    private static final String PROP_COMMAND = "getprop";
    private final HashMap<String, String> propCache = new HashMap<>(1500);
    private boolean isCacheDirty = false;
    private boolean isRelease = false;

    private PropHelper() {
    }

    /**
     * 实例Holder
     *
     * @since 2021-03-26
     */
    private static final class Holder {
        static final PropHelper INSTANCE = new PropHelper();
    }

    /**
     * 获取PropHelper实例
     *
     * @return PropHelper实例
     */
    public static PropHelper getInstance() {
        return Holder.INSTANCE;
    }

    /**
     * 读取设备属性信息，可能会阻塞主线程
     * 例如:
     * [ro.product.manufacturer]: [HUAWEI]
     *
     * @param propKey 属性值的键
     * @return 根据键查找的属性值，例如: HUAWEI
     */
    public String getProp(String propKey) {
        if (isRelease) {
            return DEFAULT_VALUE;
        }
        InputStream inputStream;
        String result = DEFAULT_VALUE;
        if (propCache.isEmpty() || isCacheDirty) {
            try {
                Process exec = Runtime.getRuntime().exec(PROP_COMMAND);
                inputStream = exec.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
                String cmdResult;
                while ((cmdResult = reader.readLine()) != null) {
                    cmdResult = cmdResult
                        .replaceAll("\\[", "")
                        .replaceAll("]", "");
                    String[] split = cmdResult.split(":");
                    if (split.length > 1) {
                        String pkey = split[0];
                        String pvalue = split[1].trim();
                        propCache.put(pkey, pvalue);
                        if (pkey.equals(propKey)) {
                            result = pvalue;
                        }
                    }
                }
                isCacheDirty = false;
            } catch (IOException e) {
                isCacheDirty = true;
            }
        }
        if (result.equals(DEFAULT_VALUE)) {
            result = propCache.get(propKey);
        }
        return result == null ? DEFAULT_VALUE : result;
    }

    /**
     * deriveFingerprint
     *
     * @return finger print
     */
    public String deriveFingerprint() {
        String finger = getProp("ro.build.fingerprint");
        if (TextUtils.isEmpty(finger)) {
            finger = getProp("ro.product.brand") + '/'
                + getProp("ro.product.name") + '/'
                + getProp("ro.product.device") + ':'
                + getProp("ro.build.version.release") + '/'
                + getProp("ro.build.id") + '/'
                + getProp("ro.build.version.incremental") + ':'
                + getProp("ro.build.type") + '/'
                + getProp("ro.build.tags");
        }
        return finger;
    }
}
